package com.jsgt.greekfire

import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.text.TextUtils
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.fhx.core.AppContext
import com.fhx.core.utils.*
import com.jsgt.greekfire.bean.YTWallet
import com.jsgt.atr.MyAppEventBusIndex
import com.jsgt.greekfire.common.util.NetDataManager
import com.jsgt.greekfire.common.util.UncaughtExceptionHandlerUtil
import com.jsgt.greekfire.receiver.NetworkChangeReceiver
import com.jsgt.greekfire.ui.home.AppConfig
import com.jsgt.greekfire.ui.main.MainGroupActivity
import com.jsgt.greekfire.ui.main.launch.LaunchActivity
import com.jsgt.wallet.MyCoreEventBusIndex
import com.scwang.smartrefresh.header.BezierCircleHeader
import com.scwang.smartrefresh.header.WaterDropHeader
import com.scwang.smartrefresh.layout.SmartRefreshLayout
import com.scwang.smartrefresh.layout.footer.ClassicsFooter
import org.greenrobot.eventbus.meta.SubscriberInfoIndex
import java.io.*
import java.util.*
import kotlin.collections.ArrayList


class App : AppContext(),ViewModelStoreOwner {
    private var CACHE_TIME = 60 * 60000 // 缓存失效时间

    private var memCacheRegion =
        Hashtable<String, Any>()

    companion object {
        lateinit var context: App
    }

    var randomHeader = 0
    var gftPrice = 0.0

    override fun onCreate() {
        super.onCreate()
        context = this
        LogUtils.isDebug = BuildConfig.DEBUG
        val eventBusIndexList = ArrayList<SubscriberInfoIndex>()
        eventBusIndexList.add(MyAppEventBusIndex())
        eventBusIndexList.add(MyCoreEventBusIndex())
        EventBusManager.init(eventBusIndexList)
        UncaughtExceptionHandlerUtil.process()
        init()
        if (LOGIN_STATUS) {
            NetDataManager.getUserAssets()
            NetDataManager.getWalletInfo()
        }
        NetDataManager.getUSTDPrice()
        registerActivityLifecycleCallbacks(ActivityLifecycleLis())


        //初始化融云
//        RongIM.init(this)

//        Pandora.get()
//            .addFunction(object : IFunc {
//                override fun onClick(): Boolean {
//                    Config.MOCK = Config.MOCK.not()
////                    toast { "当前mock:${Config.MOCK}" }
//                    return false
//                }
//
//                override fun getIcon(): Int = R.mipmap.ic_launcher
//
//                override fun getName(): String = "切换MOCK"
//
//            })
    }

    fun init() {

        try {
            val token = SharePreferencesUtil.getString(context!!, TOKEN_VALUE)
            LOGIN_STATUS = !TextUtils.isEmpty(token)
            IS_ACTIVATION = SharePreferencesUtil.getInteger(context!!, ACTIVATION_STATUS)
            MONEY_SCALE = PriceFormatUtil.format(
                SharePreferencesUtil.getFloat(context!!, MONEY_SCALE_KEY).toDouble(), 2
            ).toDouble()
            MONEY_UTIT_SCALE = PriceFormatUtil.format(
                SharePreferencesUtil.getFloat(
                    context!!,
                    MONEY_UTIT_SCALE_KEY
                ).toDouble(), 2
            ).toFloat()
        } catch (e: Exception) {

        }

        val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        registerReceiver(NetworkChangeReceiver(), filter)
        randomHeader = (0 until 2).random()
        //设置全局的Header构建器 不设置的话,默认是 贝塞尔雷达Header
        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
            layout.setPrimaryColorsId(R.color.gray_A2A2A2, R.color.yellow_E6BA12);//全局设置主题颜色
            //FalsifyHeader(context)//Falsify伪造，弄虚作假的意思,有列表反弹效果，但是没有刷新事件
            //ClassicsHeader(context)//指定为经典Header，
            //MaterialHeader(context)
            when (randomHeader % 2) {
                0 -> BezierCircleHeader(context)
                else -> WaterDropHeader(context)
            }
        }
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, layout -> //指定为经典Footer，默认是 BallPulseFooter
            ClassicsFooter(context).setDrawableSize(20f)
        }
    }

    fun login(
        ytwallet: YTWallet,
        mnemonic: String,
        name: String,
        password: String,
        backup: Boolean,
        gotoMain: Boolean
    ) {
        if (TextUtils.isEmpty(ytwallet.token)) {
            return
        }
        IS_ACTIVATION = 1//先置为未激活
        LOGIN_STATUS = true
        SharePreferencesUtil.saveString(this, TOKEN_VALUE, ytwallet.token)
        SharePreferencesUtil.saveInteger(App.context!!, ACTIVATION_STATUS, IS_ACTIVATION)
        NetDataManager.logout()
        WALLET_ADDRESS = ytwallet.address
//        WalletManager.addWallet(
//            WalletBean(
//                name,
//                ytwallet.address,
//                mnemonic,
//                Numeric.toHexStringNoPrefix(ytwallet.ecKeyPair.privateKey),
//                password,
//                backup
//            )
//        )
        if (gotoMain) {
            ActivityStackManager.finishAll()
            val intent = Intent(this, MainGroupActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        }
    }

    fun logout() {
//        LOGIN_STATUS = false
//        WALLET_ADDRESS = ""
//        IS_ACTIVATION = 1
//        SharePreferencesUtil.saveInteger(App.context!!, ACTIVATION_STATUS, IS_ACTIVATION)
//        SharePreferencesUtil.saveString(this, TOKEN_VALUE, "")
//        NetDataManager.logout()
        ActivityStackManager.finishAll()
        val intent = Intent(this, LaunchActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        startActivity(intent)
    }


    /**
     * 判断缓存数据是否可读
     *
     * @param cachefile
     * @return
     */
    private fun isReadDataCache(cachefile: String): Boolean {
        return readObject(cachefile) != null
    }

    /**
     * 判断缓存是否存在
     *
     * @param cachefile
     * @return
     */
    private fun isExistDataCache(cachefile: String): Boolean {
        var exist = false
        val data = getFileStreamPath(cachefile)
        if (data.exists()) exist = true
        return exist
    }

    /**
     * 判断缓存是否失效
     *
     * @param cachefile
     * @return
     */
    fun isCacheDataFailure(cachefile: String?): Boolean {
        var failure = false
        val data = getFileStreamPath(cachefile)
        if (data.exists() && System.currentTimeMillis() - data.lastModified() > CACHE_TIME) failure =
            true else if (!data.exists()) failure = true
        return failure
    }

    /**
     * 清除缓存目录
     *
     * @param dir
     * 目录
     * @param curTime
     * 当前系统时间
     * @return
     */
    private fun clearCacheFolder(dir: File?, curTime: Long): Int {
        var deletedFiles = 0
        if (dir != null && dir.isDirectory) {
            try {
                for (child in dir.listFiles()) {
                    if (child.isDirectory) {
                        deletedFiles += clearCacheFolder(child, curTime)
                    }
                    if (child.lastModified() < curTime) {
                        if (child.delete()) {
                            deletedFiles++
                        }
                    }
                }
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
        }
        return deletedFiles
    }

    /**
     * 将对象保存到内存缓存中
     *
     * @param key
     * @param value
     */
    fun setMemCache(key: String?, value: Any?) {
        memCacheRegion[key] = value
    }

    /**
     * 从内存缓存中获取对象
     *
     * @param key
     * @return
     */
    fun getMemCache(key: String?): Any? {
        return memCacheRegion[key]
    }

    /**
     * 保存磁盘缓存
     *
     * @param key
     * @param value
     * @throws IOException
     */
    @Throws(IOException::class)
    fun setDiskCache(key: String, value: String) {
        var fos: FileOutputStream? = null
        try {
            fos = openFileOutput("cache_$key.data", Context.MODE_PRIVATE)
            fos.write(value.toByteArray())
            fos.flush()
        } finally {
            try {
                fos!!.close()
            } catch (e: java.lang.Exception) {
            }
        }
    }

    /**
     * 获取磁盘缓存数据
     *
     * @param key
     * @return
     * @throws IOException
     */
    @Throws(IOException::class)
    fun getDiskCache(key: String): String? {
        var fis: FileInputStream? = null
        return try {
            fis = openFileInput("cache_$key.data")
            val datas = ByteArray(fis.available())
            fis.read(datas)
            String(datas)
        } finally {
            try {
                fis!!.close()
            } catch (e: java.lang.Exception) {
            }
        }
    }

    /**
     * 保存对象
     *
     * @param ser
     * @param file
     * @throws IOException
     */
    fun saveObject(ser: Serializable?, file: String?): Boolean {
        var fos: FileOutputStream? = null
        var oos: ObjectOutputStream? = null
        return try {
            fos = openFileOutput(file, Context.MODE_PRIVATE)
            oos = ObjectOutputStream(fos)
            oos.writeObject(ser)
            oos.flush()
            true
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            false
        } finally {
            try {
                oos!!.close()
            } catch (e: java.lang.Exception) {
            }
            try {
                fos!!.close()
            } catch (e: java.lang.Exception) {
            }
        }
    }

    fun delFileData(file: String?) {
        val data = getFileStreamPath(file)
        data.delete()
    }

    /**
     * 读取对象
     *
     * @param file
     * @return
     * @throws IOException
     */
    fun readObject(file: String): Serializable? {
        if (!isExistDataCache(file)) return null
        var fis: FileInputStream? = null
        var ois: ObjectInputStream? = null
        try {
            fis = openFileInput(file)
            ois = ObjectInputStream(fis)
            return ois.readObject() as Serializable
        } catch (e: FileNotFoundException) {
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            // 反序列化失败 - 删除缓存文件
            if (e is InvalidClassException) {
                val data = getFileStreamPath(file)
                data.delete()
            }
        } finally {
            try {
                ois!!.close()
            } catch (e: java.lang.Exception) {
            }
            try {
                fis!!.close()
            } catch (e: java.lang.Exception) {
            }
        }
        return null
    }

    fun containsProperty(key: String?): Boolean {
        val props = getProperties()
        return props.containsKey(key)
    }

    fun setProperties(ps: Properties?) {
        AppConfig.getAppConfig(this).set(ps)
    }

    fun getProperties(): Properties {
        return AppConfig.getAppConfig(this).get()
    }

    fun setProperty(key: String?, value: String?) {
        AppConfig.getAppConfig(this).set(key, value)
    }

    fun getProperty(key: String?): String? {
        return AppConfig.getAppConfig(this).get(key)
    }

    fun removeProperty(key: String?) {
        AppConfig.getAppConfig(this).remove(key)
    }

    override fun onLowMemory() {
        super.onLowMemory()
        viewModelStore1.clear()
    }

    private val viewModelStore1 = ViewModelStore()
    override fun getViewModelStore(): ViewModelStore {
        return viewModelStore1
    }
}